//TODO..
//lectura de telex + pierdaturno + opciones tablero
//permitir negociar despues de cada vuelta o cuando se coincida en la misma casilla
//tirar dados al principio para ver quien sale

// fallos
// telex ilegible coja otra telexOK
// telex vuelva a tirar dados OK
// telex pierda un turnoOK
// vuelo accion aeropuerto
// telex perforadoras en vez de pagar por plataforma cobra 100000
// vuelo a opep, no pierde turno

// problemas con tarjeta salida carcel, no se si se asigna bien cuando toca
// fallo pierde millon telex
// salta turno al siguiente jugador al caer en la haya?(a veces se salta algun turno)

//	m_pBanco:cBanco 															->		instancia al banco		
//	m_pTablero:cTablero 														->		instancia al tablero	
//	m_pManagerJugadores:cManagerJugadores										->		instancia al manager de jugadores		
//	m_pManagerCasillas:cManagerCasillas 										->		instancia al manager de casillas comprables
//	m_pManagerTelex:cManagerTelex 												->		instancia al manager de tarjetas telex
//	m_pManagerMensajes:ManagerMensajes  										->		instancia al manager de mensaje del juego
//	m_pDado1:cDado 																->		dado 1
//	m_pDado2:cDado 																->		dado 2
//	m_sXMLConfiguracionInicial:String 											->		configuracion inicial del juego	
//	m_pXML:XML 																	->		
//  m_pListaElementosXML:Array 													->		
//  m_pConstruirConGrupoCompleto:Boolean 										->		
//	m_pDineroInicial:uint 														->		dinero para empezar a jugar	
//	m_vBarraIniciativaJugadores:Array 											->		barra de posicionamiento de jugadores para tirar
//	m_uiJugadorActual:uint 														->		jugador en juego
//	m_pStage:Stage 																->		pantalla del juego 	
//  m_vComandoAccion:Array 														->		vector con las acciones a realizar por el juego

// public function cJuego(_st:Stage)											->		constructor
// private function Init():void													->		inicializacion de variables miembros de la clase
// public function Load(_fileXML:String):void									->		carga de xmls varios
// public function LoadComplete(_myXML:XML, _isLast:Boolean):void				->		aviso de que todos los xml se han cargado
// private function CargaElementosJuego():void									->		llama a cargaconfiguracionstandard
// public function CargaConfiguracionStandard():Boolean							->		carga de todos los xml del juego
// private function LoadTablero(_fileXML:String):Boolean						->		carga de tablero
// private function LoadCasillas(_fileXML:String):Boolean						->		carga de casillas del juego
// private function LoadTelex(_fileXML:String):Boolean							->		carga de tarjetas telex

// public function PreparacionJuego():void										->		inicializa casillas, jugadores, etc, para comenzar el juego
// private function FinInicializaJugadores():Boolean							->		cuando se tenga elegido todos los parametros opcionales del cada jugador
// public function BucleJuego():int												->		bucle para la secuencia del juego
// private function DecideJugadorActual():void									->		decidira el jugador que jugará en ese turno
// private function JugadorLanzaDados():uint									->		jugador lanza dados
// private function MueveJugadorHastaDestino():void								->		mueve jugador hasta destino
// private function ComprobacionCasillaDestino():void							->		el juego debe decidir que hara cuando un jugador cae en una casilla
// private function ComprobarGrupoCompleto(_color:String):Boolean 				->		comprueba si un jugador tiene el grupo completo de un color en concreto

// private function AplicaAccionAlJugador():void								->		dependiendo de donde ha caido el jugador, se le aplica una accion
// private function AplicaAccionTelex(_t:cTelex)								->		dependiendo de la tarjeta telex el jugador recibe una accion

// private function TransicionLanzamientoDados(e:MouseEvent):void 				->		espera para el lanzamiento de dados por un jugador
// private function TransicionOpcionComprar(e:KeyboardEvent):void 				->		pregunta a un jugador si quiere comprar una casilla
// private function TransicionComprarTorre(e:KeyboardEvent):void 				->		pregunta si se quiere comprar una torre cuando se tiene grupo completo (o no)
// private function MuestraInventarioJugador(e:KeyboardEvent):void 				->		muestra el inventario de un jugador pulsando de 0-N
// private function TransicionEntregaTarjetaSalidaHaya(e:KeyboardEvent):void 	->		pregunta si se quiere entregar la tarjeta de salida de la haya

// private function Release():void												->	

package game.juego
{
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.sampler.NewObjectSample;
	import flash.utils.ObjectInput;
	import flash.utils.Timer;
	import game.Main;
	import game.casillas.cCasilla;
	import game.casillas.cManagerCasillas;
	import game.gui.ManagerMensajes;
	import game.IXMLLoadable;
	import game.jugadores.cJugador;
	import game.jugadores.cManagerJugadores;
	import game.telex.cManagerTelex;
	import game.telex.cTelex;
	import utils.cUtils;
	import utils.LoadFiles;
	import game.CPredicates;	
	
	/**
	 * ...
	 * @author miquel
	 */
	public class cJuego implements IXMLLoadable
	{
		public static var DEBUG_PREPARACION_JUEGO:Boolean = true;
		
//Estados del juego
		static public const ESTADOINICIALIZAPROGRAMA:uint = 0;
		static public const ESTADOINICIALIZAJUGADORES:uint = 10;
		static public const ESTADOINICIALIZAJUEGO:uint = 20;
		static public const ESTADOJUEGO:uint = 30;
		static public const ESTADOJUEGOMUEVEJUGADOR:uint = 40;
		static public const ESTADOJUEGOFINMOVIMIENTOJUGADOR:uint = 50;
		static public const ESTADOFINPARTIDA:uint = 60;
		static public const ESTADOSALIRJUEGO:uint = 100;
		
//constantes del juego
		static public const DINEROCOBRARCASILLASALIDA:uint = 500000;
		static private var m_eEstadoJuego:uint = ESTADOINICIALIZAJUEGO;
		static public const TECLA_S:uint =	83;	
		static public const TECLA_0:uint =	48;	
//entidades del juego
		static private var m_pBanco:cBanco = null;
		static private var m_pTablero:cTablero = null;
		static private var m_pManagerJugadores:cManagerJugadores = null;
		static private var m_pManagerCasillas:cManagerCasillas = null;
		static private var m_pManagerTelex:cManagerTelex = null;
		static private var m_pManagerMensajes:ManagerMensajes = null;
		static private var m_pDado1:cDado = null;
		static private var m_pDado2:cDado = null;
		
//Carga XML
		static private var m_sXMLConfiguracionInicial:String = "./assets/initXML.xml";
		static private var m_pXML:XML = null;
		static private var m_pListaElementosXML:Array = null;
		
//Valores iniciales del juego
		static private var m_pConstruirConGrupoCompleto:Boolean = true;
		static private var m_pDineroInicial:uint = 0;
		
//Turnos de jugadores
		static private var m_vBarraIniciativaJugadores:Array = null;
		static private var m_uiJugadorActual:uint = 0;
		static private var m_pStage:Stage = null;
		
//Comando de acciones
		static private var m_vComandoAccion:Array = null;
//Comandos
//<"COMPRAR"><NUMJUGADOR><NOMBRECASILLA>
//<"PAGAR"><NUMJUGADORPAGADOR><ENTIDADRECEPTORA><CANTIDAD>
//<"TELEX">		
//<"SALIR_HAYA"><NUMJUGADOR>

/**
 * Constructor juego
 */
		public function cJuego(_st:Stage)
		{
			if (_st != null)
			{
				m_pStage = _st;
				Init();
			}
		}
		
/**
 * Init: Inicializacion del juego
 */
		private function Init():void
		{
			//carga de archivos xml para el juego
			m_pBanco = new cBanco();
			m_pManagerJugadores = new cManagerJugadores(this);
			m_pManagerCasillas = new cManagerCasillas(this);
			m_pManagerTelex = new cManagerTelex(this);
			m_pTablero = new cTablero(this);
			m_pManagerMensajes = new ManagerMensajes(m_pStage);
			m_pDado1 = new cDado(6);
			m_pDado2 = new cDado(6);
			LoadFiles.PreparaCargaMultiplesArchivos(4);
			
			m_vBarraIniciativaJugadores = new Array();
			m_vComandoAccion = new Array();
			
			m_pStage.removeEventListener(KeyboardEvent.KEY_UP, MuestraInventarioJugador);
			m_pStage.addEventListener(KeyboardEvent.KEY_UP, MuestraInventarioJugador);
		}
		

/* INTERFACE game.IXMLLoadable */
//Configuracion y archivos del juego
/**
 * Load: Carga de XML
 * @param	_fileXML
 */
		public function Load(_fileXML:String):void
		{
			if (Main.DEBUG_LOAD_FILES)
				trace("cJuego.as::Load::" + _fileXML + " this " + this);
			LoadFiles.CargaArchivoXML(_fileXML, this);
		}
		
/**
 * LoadComplete: recibe este mensaje cuando se ha cargado el xml y lo utiliza para componer la configuracion del juego y
 * @param	_myXML
 */
		public function LoadComplete(_myXML:XML, _isLast:Boolean):void
		{
			if (Main.DEBUG_LOAD_FILES)
				trace("cJuego.as::LoadComplete::myxml:" + _myXML);
			if (_myXML != null)
			{
				m_pXML = new XML(_myXML);
				
				//carga de elementos(durante toda la partida)
				CargaElementosJuego();
				
				if (_isLast)
				{
					PreparacionJuego();
				}
			}
			else
			{
				if (Main.DEBUG_ERRORS)
					trace("cJuego.as::LoadComplete::Fallo al cargar el xml:");
				m_eEstadoJuego = ESTADOSALIRJUEGO;
			}
		}
		

/**
 * CargaElementosJuego
 */
		private function CargaElementosJuego():void
		{
			CargaConfiguracionStandard(); //nombre de jugadores y diferentes opciones
		}

		
/**
 * CargaConfiguracionStandard: Llama a los diferentes elementos del juego para su creacion
 * @return
 */
		public function CargaConfiguracionStandard():Boolean
		{
			if (m_pXML != null)
			{
				//nombre de paths para archivos de tablero, casillas y telex
				for each (var l_item:XML in m_pXML.filesToLoad.children())
				{
					if (l_item.@tablero != undefined)
					{
						if (Main.DEBUG_LOAD_FILES)
							trace("cJuego.as::CargaConfiguracionStandard:TABLERO:" + l_item.@tablero + "\n");
						LoadTablero(l_item.@tablero);
					}
					
					if (l_item.@casillas != undefined)
					{
						if (Main.DEBUG_LOAD_FILES)
							trace("cJuego.as::CargaConfiguracionStandard:CASILLAS:" + l_item.@casillas + "\n");
						LoadCasillas(l_item.@casillas);
					}
					
					if (l_item.@telex != undefined)
					{
						if (Main.DEBUG_LOAD_FILES)
							trace("cJuego.as::CargaConfiguracionStandard:TELEX:" + l_item.@telex + "\n");
						LoadTelex(l_item.@telex);
					}
				}
				
				//composicion de jugadores del juego
				if (m_pManagerJugadores != null)
				{
					var l_uiNumPlayer:uint = 0;
					for each (var l_player:XML in m_pXML.players.children())
					{
						//trace(">>>>>>>>>>cJuego.as::CargaConfiguracionStandard::" + l_player.@name + ":" + l_player.@color);
						var l_pJugador:cJugador = new cJugador();
						
						if (l_pJugador != null)
						{
							l_pJugador.m_uiNumJugador = l_uiNumPlayer++;
							l_pJugador.SetName(l_player.@name);
							l_pJugador.SetColor(l_player.@color);
							
							var l_iLenghtVector:uint = m_pManagerJugadores.GetVectorJugadores().push(l_pJugador);
							
							if (Main.DEBUG_LOAD_FILES)
								trace("cJuego.as::CargaConfiguracionStandard:Añadido:" + l_pJugador.GetName() + " en el vector de jugadores del manager de jugadores. Total=" + l_iLenghtVector);
						}
					}
				}
				
				//parametros opcionales del juego
				for each (var l_basegame:XML in m_pXML.baseGame.children())
				{
					if (Main.DEBUG_LOAD_FILES)
						trace("cJuego.as::CargaConfiguracionStandard:basegame:" + l_basegame.@money + ":" + l_basegame.@buildWithCompleteGroup);
					m_pDineroInicial = l_basegame.@money;
					m_pConstruirConGrupoCompleto = l_basegame.@buildWithCompleteGroup;
				}
			}
			
			return true;
		}
		
/**
 * LoadTablero: Carga de las casillas del tablero, su distribucion, etc...
 * @param	_fileXML xml con la info
 * @return si la carga es correcta
 */
		private function LoadTablero(_fileXML:String):Boolean
		{
			if (m_pTablero != null)
			{
				m_pTablero.Load(_fileXML);
				return true;
			}
			return false;
		}
		
/**
 * LoadCasillas: Carga de las casillas de propiedades
 * @param	_fileXML xml con la info
 * @return si la carga es correcta
 */
		private function LoadCasillas(_fileXML:String):Boolean
		{
			if (m_pManagerCasillas != null)
			{
				m_pManagerCasillas.Load(_fileXML);
				return true;
			}
			
			return false;
		}
		
/**
 * LoadTelex: Carga de tarjetas telex
 * @param	_fileXML xml con la info
 * @return si la carga es correcta
 */
		private function LoadTelex(_fileXML:String):Boolean
		{
			if (m_pManagerTelex != null)
			{
				m_pManagerTelex.Load(_fileXML);
				return true;
			}
			
			return false;
		}
		
/**
 * PreparacionJuego: Los jugadores pueden elegir sus caracteristicas, el juego se inicializa y prepara el bucle del juego
 */
		public function PreparacionJuego():void
		{
//			trace("cJuego.as::PreparacionJuego::********************");
			switch (m_eEstadoJuego)
			{
				case ESTADOINICIALIZAJUGADORES:
					
					//menu similar a heroes. Gestiona OnEnterFrame.
					if (FinInicializaJugadores())
					{
						m_eEstadoJuego = ESTADOINICIALIZAJUEGO;
					}
					
					break;
				
				//prepara jugadores, dinero, telex... para empezar juego	
				case ESTADOINICIALIZAJUEGO: 
					//al inicio todas las casillas del banco
					if (DEBUG_PREPARACION_JUEGO) trace("cJuego.as::PreparacionJuego:CASILLAS BANCO:");
					m_pManagerJugadores.GetVectorJugadores().forEach( CPredicates.SetJugadoresCasillasSinPropietario );

					
					if (DEBUG_PREPARACION_JUEGO) trace("cJuego.as::PreparacionJuego:REPARTO DINERO:");
					m_pBanco.RepartoDinero(m_pManagerJugadores, m_pDineroInicial);
					
					if (DEBUG_PREPARACION_JUEGO) trace("cJuego.as::PreparacionJuego:JUGADORES TABLERO:");
					//posiciona jugadores en la salida
					m_pManagerJugadores.GetVectorJugadores().forEach(CPredicates.SetJugadoresCasillaInicial);

					//mezcla tarjetas
					if (DEBUG_PREPARACION_JUEGO) trace("cJuego.as::PreparacionJuego:MEZCLA TELEX:");
					// TODO.. bloqueo de mezcla de tarjetas
					// m_pManagerTelex.MezclaTarjetas();

					
					m_eEstadoJuego = ESTADOJUEGO;
					PreparacionJuego();
					break;
				
				case ESTADOJUEGO: 
					//Inicio Juego
					if (BucleJuego() != ESTADOFINPARTIDA)
					{
						trace("cJuego.as::PreparacionJuego::juega");
					}
					
					m_eEstadoJuego = ESTADOJUEGOMUEVEJUGADOR;
					BucleJuego();
					
					break;
			
			}
		}
		
/**
 * TODO..
 * FinInicializaJugadores: cuando se tenga elegido todos los parametros opcionales del cada jugador
 * @return
 */
		private function FinInicializaJugadores():Boolean
		{
			//TODO.. resolver menu de jugadores
			return true;
		}
		
/**
 * BucleJuego: Desarrollo del juego
 */
		public function BucleJuego():int
		{
			switch (m_eEstadoJuego)
			{
				case ESTADOJUEGOMUEVEJUGADOR: 
					//trace("cJuego.as::BucleJuego:********************************:");
					DecideJugadorActual();
	
					m_pManagerMensajes.GeneraMensaje("LANZAMIENTO", m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual]); //Espera pulsacion de boton aceptar o pulsacion tecla
					m_pStage.addEventListener(MouseEvent.MOUSE_UP, TransicionLanzamientoDados);
					break;
				
				case ESTADOJUEGOFINMOVIMIENTOJUGADOR:
					m_pStage.removeEventListener(MouseEvent.MOUSE_UP, TransicionLanzamientoDados);
					
					MueveJugadorHastaDestino(); //Comprueba jugadores que estan en esa casilla para 
					//posicionar la ficha correctamente, hacer interpolacion lineal entre posicion actual y siguiente
					
					ComprobacionCasillaDestino(); //gestor acciones y mensajes
					
					break;
				
				case ESTADOFINPARTIDA: 
					break;
			}
			
			return m_eEstadoJuego;
		}
		
/**
 * DecideJugadorActual: obtiene el siguiente jugador de la cola
 * @return
 */
		private function DecideJugadorActual():void
		{
			// si la barra esta vacia
			if (m_vBarraIniciativaJugadores.length == 0)
			{
				m_vBarraIniciativaJugadores = ( m_pManagerJugadores.GetVectorJugadores().concat() );
			}

			var l_pJugador:cJugador = m_vBarraIniciativaJugadores.shift();
			// siguiente jugador a tirar, si no espera el siguiente de la barra de iniciativa sera el, sino el siguiente que no tenga que esperar
			m_uiJugadorActual = l_pJugador.m_uiNumJugador;
			trace("cJuego.as::DecideJugadorActual:m_uiJugadorActual:" + m_uiJugadorActual + ":name:" + m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual].GetName());

		}
		
		
/**
 * MueveJugadorHastaDestino: Mueve al jugador correspondiente a la casilla donde le han tocado los dados teniendo en cuenta las casillas del tablero
 */
		private function MueveJugadorHastaDestino():void
		{
			var l_pJugadorActual:cJugador = m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual];
			var l_uiCasillaAnteriorDelJugador:uint = l_pJugadorActual.GetCasillaActual();
			
			var l_uiDados:uint = l_pJugadorActual.LanzaDados(m_pDado1, m_pDado2);

			//posiciona jugador en la casilla correspondiente
			l_pJugadorActual.SetCasillaActual((l_uiCasillaAnteriorDelJugador + l_uiDados) % m_pTablero.GetVectorTablero().length);
			var l_uiCasillaActualDelJugador:uint = l_pJugadorActual.GetCasillaActual();
			
			//pase por la casilla de salida
			if (l_uiCasillaActualDelJugador < l_uiCasillaAnteriorDelJugador)
			{
				l_pJugadorActual.AddDinero(DINEROCOBRARCASILLASALIDA);
				trace("cJuego.as::MueveJugadorHastaDestino::" + l_pJugadorActual.GetName() + " obtiene " + DINEROCOBRARCASILLASALIDA + " POR LLEGAR DE NUEVO A LA SALIDA");
			}
			
			trace("cJuego.as::MueveJugadorHastaDestino::" + l_pJugadorActual.GetName() + ":saca:" + l_uiDados); 
			trace("cJuego.as::MueveJugadorHastaDestino::" + l_pJugadorActual.GetName() + ":numero:" + m_pTablero.GetVectorTablero()[l_pJugadorActual.GetCasillaActual()]._numero + ":nombre:" + m_pTablero.GetVectorTablero()[l_pJugadorActual.GetCasillaActual()]._nombre);
		}
		
/**
 * ComprobacionCasillaDestino: Diferentes casuisticas
 * 		si es casilla de propiedad se realizan las siguientes acciones: 	<COMPRAR>	
 * 																			<COMPRAR_TORRE> 	
 * 																			<PAGAR>			
 * 																			<NOP>
 * 		
 *		si es una casilla auxiliar de tablero hay las siguientes acciones:	<TELEX>			
 * 																			<IR_HAYA>		
 * 																			<HAYA>		
 * 																			<VUELVEJUGAR>
 * 																			<OPEP>
 * 																			<SERVICIO>
 * 																			<BLANCA>
 */
		private function ComprobacionCasillaDestino():void
		{
			//posiciona jugador en la casilla correspondiente
			var l_pJugadorActual:cJugador = m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual];
			var l_uiCasillaActualDelJugador:uint = l_pJugadorActual.GetCasillaActual();
			var l_sNombreCasillaDestino:String = m_pTablero.GetVectorTablero()[l_uiCasillaActualDelJugador]._nombre;
			
			var casilla:cCasilla = m_pManagerCasillas.GetCasillaByName(l_sNombreCasillaDestino);
			
			// con esta condicion sabremos si es una casilla de propiedad (!=null) o no (== null)
			if (casilla != null)
			{
				trace("cJuego.as::ComprobacionCasillaDestino:HAS CAIDO EN :" + casilla.GetNombre() + ":PRECIO:" + casilla.m_uiPrecio);
				switch(casilla.GetPropietario())
				{
					//si la casilla no tiene dueño
					case 0xFF:
						trace("cJuego.as::ComprobacionCasillaDestino:PULSA 'S' PARA COMPRAR, OTRA TECLA PARA PASAR:");

						//instruccion
						m_vComandoAccion.push(l_sNombreCasillaDestino);
						m_vComandoAccion.push(m_uiJugadorActual);
						
						m_pStage.addEventListener(KeyboardEvent.KEY_UP, TransicionOpcionComprar);
						break;
						
					//si es del propio jugador
					case m_uiJugadorActual:
						trace("cJuego.as::ComprobacionCasillaDestino:COMPROBAR SI TIENES GRUPO COMPLETO:");
						if (  ComprobarGrupoCompleto(casilla.m_sColor) )
						{
							//<"COMPRAR_TORRE"><NUMJUGADORPAGADOR><NOMBRECASILLA><CANTIDAD>
							//TODO..
//							m_vComandoAccion.push(PRECIOTORREOPLATAFORMA);
							m_vComandoAccion.push(l_sNombreCasillaDestino);
							m_vComandoAccion.push(m_uiJugadorActual);
							trace("cJuego.as::ComprobacionCasillaDestino:HAY GRUPO COMPLETO!!!!:");
							trace("cJuego.as::ComprobacionCasillaDestino:PULSA 4 PARA COMPROBAR SI QUIERES COMPRAR TORRE O PLATAFORMA, OTRA TECLA PARA PASAR:");
							m_pStage.addEventListener(KeyboardEvent.KEY_UP, TransicionComprarTorre);
						}
						else
						{
							trace("cJuego.as::ComprobacionCasillaDestino:NO HAY GRUPO COMPLETO, NO SE PUEDE CONSTRUIR:");
							//No hay ninguna accion
							m_vComandoAccion.push("NOP");
							AplicaAccionEnTransicionAlJugador();
						}
						
						break;
						
					//si es de otro jugador
					default:
						var l_uiPago:uint = 0;
						if (casilla.m_uiNumTorres == 0)
						{
							if (casilla.m_bGrupoCompleto)
							{
								l_uiPago = casilla.m_uiPrecio / 20;
							}
							else
							{
								l_uiPago = casilla.m_uiPrecio / 10;
							}
						}
						else
						{
							l_uiPago = (casilla.m_uiPrecio / 2) * casilla.m_uiNumTorres;
						}

						
						//<"PAGAR"><NUMJUGADORPAGADOR><ENTIDADRECEPTORA><CANTIDAD>
						m_vComandoAccion.push(l_uiPago);
						m_vComandoAccion.push(casilla.GetPropietario());
						m_vComandoAccion.push(m_uiJugadorActual);
						m_vComandoAccion.push("PAGAR");
						
						//trace("cJuego.as::ComprobacionCasillaDestino:TIENES QUE PAGAR:" + l_uiPago);
						AplicaAccionEnTransicionAlJugador();
						break;
				}
			}
			else  //no es una casilla de propiedad
			{
				trace("cJuego.as::ComprobacionCasillaDestino:CASILLA ESPECIAL!!!:HAY QUE APLICAR AL JUGADOR LA CASILLA ESPECIAL " + l_sNombreCasillaDestino);
				switch (l_sNombreCasillaDestino)
				{
					case "TELEX":
						m_vComandoAccion.push("TELEX");
						break;
					
					case "IR_HAYA":
						m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual].MueveHastaCasilla("HAYA", m_pTablero);
						//break;
			
					case "HAYA":
						m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual].SetTurnosEspera(3);
						break;
					
					case "OPEP":
					case "BLANCA":
						m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual].SetTurnosEspera(1);
						break;
						
					case "SERVICIO":
						//<"PAGAR"><NUMJUGADORPAGADOR><ENTIDADRECEPTORA><CANTIDAD>
						
						var l_pJugador:cJugador = m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual];
						trace("cJuego.as:ComprobacionCasillaDestino:El jugador " + l_pJugador.GetName() + " tiene " + l_pJugador.GetDinero());
						l_pJugador.AddDinero( -100000 );
						trace("cJuego.as:ComprobacionCasillaDestino:CASILLA:Area de servicio:TIENES QUE PAGAR: 100000P$" );
						trace("cJuego.as:ComprobacionCasillaDestino:El jugador " + l_pJugador.GetName() + " tras pagar tiene " + l_pJugador.GetDinero());
						break;
						
					case "VUELVETIRAR":	
						m_vBarraIniciativaJugadores.unshift(m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual]);		
						break;

					default:
						trace("cJuego.as::ComprobacionCasillaDestino:QUE CASILLA ES ESA??:");
					break;
				}
				
				
				AplicaAccionEnTransicionAlJugador(); //gestor acciones y mensajes
			}
		}
		

		private function ComprobarGrupoCompleto(_color:String):Boolean 
		{
			var l_vVectorCasillas:Array = m_pManagerCasillas.GetVectorCasillas();
			
			var i:uint = 0;
			var l_bRepasoLista:Boolean = true;
			
			while(i < l_vVectorCasillas.length && l_bRepasoLista)
			{
				if (cCasilla(l_vVectorCasillas[i]).m_sColor == _color)
				{
					if(cCasilla(l_vVectorCasillas[i]).GetPropietario() != m_uiJugadorActual)
					{
						l_bRepasoLista = false;
					}
				}	
				
				i++;
			}
			
			return l_bRepasoLista;
		}
		
		
/**
 * AplicaAccionEnTransicionAlJugador
 */
		private function AplicaAccionEnTransicionAlJugador():void
		{			
			//init
			var l_pJugador:cJugador = null;
			var l_pContrincante:cJugador = null;
			var l_pCasilla:cCasilla = null;
			
			trace("cJuego.as::AplicaAccionEnTransicionAlJugador:m_vComandoAccion:" + m_vComandoAccion);
			var l_accion:Object = m_vComandoAccion.pop();
			switch(l_accion)
			{
				case "COMPRAR":
					var l_uiJugador:uint = m_vComandoAccion.pop();
					var l_sCasilla:String = m_vComandoAccion.pop();
					//Da propiedad a jugador
					l_pJugador = m_pManagerJugadores.GetVectorJugadores()[l_uiJugador];
					l_pJugador.GetListaPropiedades().push(l_sCasilla);
					
					//la casilla es propiedad del jugador en el manager de casillas
					l_pCasilla= m_pManagerCasillas.GetCasillaByName(l_sCasilla);
					l_pCasilla.SetPropietario(l_uiJugador);
					
					//el jugador paga
					l_pJugador.AddDinero( -l_pCasilla.m_uiPrecio);
					
					trace("cJuego.as::AplicaAccionAlJugador:El jugador:" + l_pJugador.GetName() + ":ha comprado:" + l_pCasilla.GetNombre() + ":por:" + l_pCasilla.m_uiPrecio + "P$. Ahora dispone de:" + l_pJugador.GetDinero());
					break;
					
				case "PAGAR":
					//<"PAGAR"><NUMJUGADORPAGADOR><ENTIDADRECEPTORA><CANTIDAD>
					l_uiJugador = m_vComandoAccion.pop();
					var l_uiCobrador:uint = m_vComandoAccion.pop();
					var l_uiCantidad:uint = m_vComandoAccion.pop();
					
					//quita dinero a jugador
					l_pJugador = m_pManagerJugadores.GetVectorJugadores()[l_uiJugador];
					l_pJugador.AddDinero( -l_uiCantidad);
					
					//da dinero al contrincante
					l_pContrincante = m_pManagerJugadores.GetVectorJugadores()[l_uiCobrador];
					l_pContrincante.AddDinero(l_uiCantidad);		
					
					trace("cJuego.as::AplicaAccionAlJugador:El jugador:" + l_pJugador.GetName() + ":paga:" + l_uiCantidad + ":a:" + l_pContrincante.GetName());
					trace("cJuego.as::AplicaAccionAlJugador:El jugador:" + l_pJugador.GetName() + ":tiene:" + l_pJugador.GetDinero() + "P$:y:" + l_pContrincante.GetName() + ":tiene:" + l_pContrincante.GetDinero() + "P$.");	
					break;
				
				case "TELEX":
					//<"TELEX">
					l_pJugador = m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual];
					var l_tTelex:cTelex = m_pManagerTelex.LeerTarjeta();
					//trace(l_tTelex.print());
					trace("cJuego.as::AplicaAccionAlJugador:TELEX:" + l_tTelex.m_sMensaje + ":ACCION:" + l_tTelex.m_pAccion + ":JUGADOR ACTUAL:" + l_pJugador.GetName() + ":TERCERO:" + l_tTelex.m_pTercero);
					AplicaAccionTelex(l_tTelex);
					break;
					
				case "SALIR_HAYA":
					//<SALIR_HAYA><NUMJUGADOR>
					
					l_uiJugador = m_vComandoAccion.pop();
					l_pJugador = m_pManagerJugadores.GetVectorJugadores()[l_uiJugador];
					
					trace("cJuego.as::AplicaAccionAlJugador:El jugador:" + l_pJugador.GetName() + " SALE DE LA HAYA");
					//descuenta el turno de espera
					l_pJugador.SetTurnosEspera(0);
					//busca hasta encontrar un jugador que pueda tirar
					m_vBarraIniciativaJugadores.unshift(l_pJugador);
					
//					DecideJugadorActual();
					break;
					
				case "NOP":
					while (m_vComandoAccion.length > 0)
					{
						var l_n:Object = m_vComandoAccion.pop();
						trace("cJuego.as::AplicaAccionAlJugador:l_n*****:" + l_n);
					}
					break;
			}
			
			m_eEstadoJuego = ESTADOJUEGO;
			PreparacionJuego();
		}

		
		private function AplicaAccionTelex(_t:cTelex):void
		{
		//	var l_pAccion:int = parseInt(_t.m_pAccion);
			var l_vJugadores:Array = m_pManagerJugadores.GetVectorJugadores();
			
			
		//	trace("***** accion ****** " + l_pAccion);
			if (!cUtils.IsNumber(_t.m_pAccion))						/*	Cuando la accion es una cantidad numerica: dinero*/
			{
				//trace("***** accion (isNAN) de  " + _t.m_pTercero);
				switch(_t.m_pTercero)
				{
					case "banco":						/*	TELEX:	TERCERO -> BANCO	*/
						if (_t.m_pAccion == "100000xP")		
						{
						}
						break;
												
					case "tablero":						/*	TELEX: TERCERO -> TABLERO	*/
						trace("***** accion de tablero " + _t.m_pAccion);
						if (_t.m_pAccion == "haya")
						{
							l_vJugadores[m_uiJugadorActual].MueveHastaCasilla("HAYA", m_pTablero);
						}
						else if (_t.m_pAccion == "aeropuerto")
						{
							l_vJugadores[m_uiJugadorActual].MueveHastaCasilla("SALIDA", m_pTablero);
						}
						else if (_t.m_pAccion == "opep")
						{
							l_vJugadores[m_uiJugadorActual].MueveHastaCasilla("OPEP", m_pTablero);
						}
						else if (_t.m_pAccion == "abudhabi")
						{
							l_vJugadores[m_uiJugadorActual].MueveHastaCasilla("ABU DHABI", m_pTablero);
						}

						ComprobacionCasillaDestino();
						
						break;

					case "juego":						/*	TELEX:	TERCERO -> JUEGO	*/
						trace("***** accion de juego " + _t.m_pAccion);
						switch(_t.m_pAccion)
						{
							case "vuelvejugar":
								m_vBarraIniciativaJugadores.unshift(l_vJugadores[m_uiJugadorActual]);
								break;
							case "pierdaturno":
								l_vJugadores[m_uiJugadorActual].SetTurnosEspera(1);
								break;
							case "salidacarcel":
								l_vJugadores[m_uiJugadorActual].AddTelexToLeaveHaya();
								break;
								
							default:
								trace("QUE ACCION ES??")
								break;
						}
						break;
						
					case "telex":						/*	TELEX:	TERCERO -> TELEX	*/
						trace("***** accion de telex ");
						m_vComandoAccion.push("TELEX");
						AplicaAccionEnTransicionAlJugador()
						break;
										
					default:
						if(Main.DEBUG_WARNINGS) trace("cJuego.as::AplicaAccionTelex:NO SE PUEDE APLICAR LA TARJETA:" + _t.m_uiNumTarjetaTelex);
						break;
				}
			}
			else //pagos
			{
				if (_t.m_pTercero == "banco")
				{
					trace("cJuego.as::AplicaAccionTelex:el jugador:" + l_vJugadores[m_uiJugadorActual].GetName() + " tenia " + l_vJugadores[m_uiJugadorActual].GetDinero() );
					l_vJugadores[m_uiJugadorActual].AddDinero(_t.m_pAccion);
					trace("cJuego.as::AplicaAccionTelex:y aplicando operacion en telex tiene:" + l_vJugadores[m_uiJugadorActual].GetDinero());
				}
				else if (_t.m_pTercero == "todos")
				{
					// Todos los jugadores pagan 100000 al jugador actual
					for (var i:uint = 0; i < l_vJugadores.length; i++ )
					{
						l_vJugadores[i].AddDinero( -100000 );
						l_vJugadores[m_uiJugadorActual].AddDinero( 100000 );
						trace("cJuego.as::AplicaAccionTelex:el jugador:" + l_vJugadores[i].GetName() + " paga 100000 a " + l_vJugadores[m_uiJugadorActual].GetDinero() );
					}
				}
			}
		}
		
		private function Release():void
		{
			//if (m_pXML != null)
			//{
			//delete m_pXML;
			//m_pXML  = null;
			//}
		}

//--------------------------------------------------------------------------------------------------------------------------------------------		
//E V E N T O S ------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------------		
/**
 * OpcionComprar
 * @param	e
 */
		private function TransicionOpcionComprar(e:KeyboardEvent):void 
		{
			if(e.keyCode < TECLA_0 || (e.keyCode > TECLA_0 + m_pManagerJugadores.GetVectorJugadores().length - 1))
			{
				if (e.keyCode == TECLA_S) //"S" o "s"
				{
	//				trace("cJuego.as::OpcionComprar:COMPRA:" );
					m_vComandoAccion.push("COMPRAR");
				}
				else
				{
	//				trace("cJuego.as::OpcionComprar:NO COMPRA:");
					m_vComandoAccion.push("NOP");
				}

				AplicaAccionEnTransicionAlJugador(); //gestor acciones y mensajes		
				
				m_pStage.removeEventListener(KeyboardEvent.KEY_UP, TransicionOpcionComprar); 
			}
		}
		

/**
 * Mostrar Inventario
 * @param	e
 */
		private function MuestraInventarioJugador(e:KeyboardEvent):void 
		{
			if (e.keyCode < TECLA_0 || e.keyCode > (TECLA_0 + m_pManagerJugadores.GetVectorJugadores().length - 1)) 
			{
				return;
			}
			var l_pJugador:cJugador = m_pManagerJugadores.GetVectorJugadores()[e.keyCode - TECLA_0];
			
			trace("cJuego.as::MuestraInventarioJugador:NOMBRE:" + l_pJugador.GetName() + "(" + l_pJugador.GetDinero() + ") Esta en la casilla:" + l_pJugador.GetCasillaActual());
			
			
			var len:uint = l_pJugador.GetListaPropiedades().length;
			
			for (var i:uint = 0; i < len; i++) 
			{
				var l_pCasilla:cCasilla = m_pManagerCasillas.GetCasillaByName(l_pJugador.GetListaPropiedades()[i]);
				trace("PROPIEDAD::" + i + "-" + l_pCasilla.GetNombre() + "->" + l_pCasilla.m_sColor + "\t(" + l_pCasilla.GetGrupo() + ")");
			}
		}

		
/**
 * ComprarTorre
 * @param	e
 */
		private function TransicionComprarTorre(e:KeyboardEvent):void 
		{
			//Discrimina numeros
			if(e.keyCode < TECLA_0 || (e.keyCode > TECLA_0 + m_pManagerJugadores.GetVectorJugadores().length - 1))
			{
				if (e.keyCode == 84) //"T" o "t"
				{
					trace("cJuego.as::OpcionComprar:COMPRA TORRE:" );
					m_vComandoAccion.push("COMPRAR_TORRE");
				}
				else
				{
					m_vComandoAccion.push("NOP");
					trace("cJuego.as::OpcionComprar:NO COMPRA TORRE:");

				}
			}
			
			AplicaAccionEnTransicionAlJugador(); //gestor acciones y mensajes		
			m_pStage.removeEventListener(KeyboardEvent.KEY_UP, TransicionComprarTorre); 
		}
		

		private function TransicionLanzamientoDados(e:MouseEvent):void 
		{
			var l_bSiguenteJugador:Boolean = true;
			var l_pJugador:cJugador = m_pManagerJugadores.GetVectorJugadores()[m_uiJugadorActual];
			//talvez en salidahaya
//					var l_pJugador:cJugador = m_vBarraIniciativaJugadores.shift();

			if (l_pJugador.GetTurnosEspera() > 0)
			{
				if (l_pJugador.HasTelexToLeaveHaya())
				{
					trace("TIENES TARJETA TELEX PARA SALIR DE LA HAYA, PULSA 'S' PARA UTILIZARLA, OTRA TECLA PARA GUARDARLA...")
					m_pStage.addEventListener(KeyboardEvent.KEY_UP, TransicionEntregaTarjetaSalidaHaya);
					l_bSiguenteJugador = false;
				}
				else
				{
	//					trace("cJuego.as::DecideJugadorActual:name:" + l_pJugador.GetName() + " NO JUEGA ESTE TURNO");
					//descuenta el turno de espera
					trace("cJuego.as::DecideJugadorActual:name:" + l_pJugador.GetName() + " LE QUEDAN " + (l_pJugador.GetTurnosEspera()) + " TURNOS");
					l_pJugador.DecrementaTurnosEspera();
					//busca hasta encontrar un jugador que pueda tirar
					DecideJugadorActual();
				}
			}

			if (l_bSiguenteJugador)
			{
				m_eEstadoJuego = ESTADOJUEGOFINMOVIMIENTOJUGADOR;
				BucleJuego();
			}
		}

		
		private function TransicionEntregaTarjetaSalidaHaya(e:KeyboardEvent):void 
		{
			//Discrimina numeros
			if(e.keyCode < TECLA_0 || (e.keyCode > TECLA_0 + m_pManagerJugadores.GetVectorJugadores().length - 1))
			{
				if (e.keyCode == TECLA_S) //"S" o "s"
				{
					
	//				trace("cJuego.as::OpcionComprar:COMPRA:" );
					m_vComandoAccion.push(m_uiJugadorActual);
					m_vComandoAccion.push("SALIR_HAYA");
				}
				else
				{
	//				trace("cJuego.as::OpcionComprar:NO COMPRA:");
					m_vComandoAccion.push("NOP");
				}

				AplicaAccionEnTransicionAlJugador(); //gestor acciones y mensajes		
				
				m_pStage.removeEventListener(KeyboardEvent.KEY_UP, TransicionEntregaTarjetaSalidaHaya); 
			}
		}
		
		
	}

}